/**
 * This file is part of iSecurePasswords.
 *
 *   iSecurePasswords is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   iSecurePasswords is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with iSecurePasswords.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * Author: Matthew MacGregor
 * Created: 2012
 * iSecurePasswords, copyright 2013 Sudolink, LLC
 * 
 */ 
package com.sudolink.cryptodata;

import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName;
import com.sudolink.crypto.AESCrypto;
import com.sudolink.crypto.CryptoException;
import com.sudolink.isp.enums.DatabaseVersion;
import com.sudolink.isp.enums.EncryptionVersion;

/**
 *
 * @author matsu
 */
public class IOContainer {

    @SerializedName("isp")
    public Data instance;
    
    public IOContainer() {
        instance = new Data();
    }
    
    public class Data {

        private String checksum;
        private byte[] salt;
        private DatabaseVersion dbVersion;
        private EncryptionVersion encryptionVersion;
        private String data;

        /**
         * @return the checksum
         */
        public String getChecksum() {
            return checksum;
        }

        /**
         * @param checksum the checksum to set
         */
        public void setChecksum(String checksum) {
            this.checksum = checksum;
        }

        /**
         * @return the version
         */
        public DatabaseVersion getDBVersion() {
            return dbVersion;
        }

        /**
         * @param version the version to set
         */
        public void setDBVersion(DatabaseVersion version) {
            dbVersion = version;
        }

        /**
         * @param bundle
         * @return the data
         * @throws com.sudolink.crypto.CryptoException
         */
        public String getData(CryptInfoBundle bundle) throws CryptoException {
            return decrypt(data, bundle);
        }

        /**
         * @param data the data to set
         * @param bundle
         * @throws com.sudolink.crypto.CryptoException
         */
        public void setData(String data, CryptInfoBundle bundle) throws CryptoException {
            this.data = encrypt(data, bundle);
        }

        private String encrypt(String data, CryptInfoBundle bundle) throws CryptoException {
            byte[] bytes = data.getBytes();
            AESCrypto c = new AESCrypto();
            return c.encrypt(bytes, bundle.getPassword(), bundle.getSalt());
        }

        private String decrypt(String cData, CryptInfoBundle bundle) throws CryptoException {
            AESCrypto c = new AESCrypto();
            byte[] v = c.decrypt(cData, bundle.getPassword(), bundle.getSalt());
            return new String(v);
        }

        /**
         * @return the salt
         */
        public byte[] getSalt() {
            return salt;
        }

        /**
         * @param salt the salt to set
         */
        public void setSalt(byte[] salt) {
            this.salt = salt;
        }

        /**
         * @return the encryptionVersion
         */
        public EncryptionVersion getEncryptionVersion() {
            return encryptionVersion;
        }

        /**
         * @param encryptionVersion the encryptionVersion to set
         */
        public void setEncryptionVersion(EncryptionVersion encryptionVersion) {
            this.encryptionVersion = encryptionVersion;
        }
    }

    public String toJson() {
        Gson gson = new Gson();
        return gson.toJson(instance);
    }

    //CryptInfoBundle.setSalt() happens here...
    //TODO: Make this better.
    public void fromJson(String json, CryptInfoBundle bundle) {
        Gson gson = new Gson();
        instance = gson.fromJson(json, Data.class);
        bundle.setSalt(instance.getSalt());
    }
}
